
surface.CreateFont("Trebuchet",16,400,true,false,"Trebuchet16")
surface.CreateFont("Trebuchet",32,400,true,false,"Trebuchet32")
surface.CreateFont("Trebuchet",40,400,true,false,"Trebuchet40")
surface.CreateFont("Liberation Mono Bold",24,400,false,false,"LCEdit24")
surface.CreateFont("Liberation Mono Bold",16,400,false,false,"LCEdit16")

//Library
if not lclib then
	lclib = {}
	lclib.tex_corner8 = surface.GetTextureID("gui/corner8")
	lclib.tex_corner16 = surface.GetTextureID("gui/corner16")
	lclib.tex_file = surface.GetTextureID("VGUI/spawnmenu/file")
	lclib.tex_folder = surface.GetTextureID("VGUI/spawnmenu/folder")
	lclib.tex_gradient = surface.GetTextureID("gui/gradient")
else
	old = lclib
	lclib = {}
	lclib.tex_corner8 = old.tex_corner8
	lclib.tex_corner16 = old.tex_corner16
	lclib.tex_file = old.tex_file
	lclib.tex_folder = old.tex_folder
	lclib.tex_gradient = surface.GetTextureID("gui/gradient")
end

lclib.colors = {
	panel = {
		label = "Panel",
		color = Color(63,63,63),
	},
	panel_inactive = {
		label = "Panel Inactive",
		color = Color(31,31,31),
	},
	panel_highlight = {
		label = "Panel Highlight",
		color = Color(0,0,255),
	},
	panel_press = {
		label = "Panel Press",
		color = Color(255,0,0),
	},
	panel_text = {
		label = "Panel Text",
		color = Color(255,255,255),
	},
	edit_background = {
		label = "Edit Background",
		color = Color(255,255,255),
	},
	edit_highlight = {
		label = "Edit Highlight",
		color = Color(0,0,255),
	},
	edit_press = {
		label = "Edit Press",
		color = Color(255,0,0),
	},
	edit_text = {
		label = "Edit Text",
		color = Color(0,0,0),
	},
	button_background = {
		label = "Button Background",
		color = Color(127,127,127),
	},
	button_active = {
		label = "Button Background",
		color = Color(0,255,0),
	},
	button_highlight = {
		label = "Button Highlight",
		color = Color(0,0,127),
	},
	button_press = {
		label = "Button Press",
		color = Color(255,0,0),
	},
	button_text = {
		label = "Button Text",
		color = Color(255,255,255),
	},
}

lclib.inRectBounds = function(x,y,x1,y1,x2,y2)
	if x >= x1 and x <= x2 and y >= y1 and y <= y2 then
		return true
	end
	return false
end
lclib.inRectBoundsE = function(x,y,x1,y1,x2,y2)
	if x >= x1 and x < x2 and y >= y1 and y < y2 then
		return true
	end
	return false
end
lclib.inRectBoundsW = function(x,y,x1,y1,x2,y2)
	if x >= x1 and x <= x2+x1 and y >= y1 and y <= y2+y1 then
		return true
	end
	return false
end
lclib.inRectBoundsWE = function(x,y,x1,y1,x2,y2)
	if x >= x1 and x < x2+x1 and y >= y1 and y < y2+y1 then
		return true
	end
	return false
end
lclib.inBounds = function(a,min,max)
	if a >= min and a <= max then
		return true
	end
	return false
end
lclib.inBoundsE = function(a,min,max)
	if a >= min and a < max then
		return true
	end
	return false
end
lclib.inBoundsW = function(a,min,max)
	if a >= min and a <= min+max then
		return true
	end
	return false
end
lclib.inBoundsWE = function(a,min,max)
	if a >= min and a < min+max then
		return true
	end
	return false
end
lclib.drawTab = function(x,y,w,h)
	surface.DrawRect(x+8,y,w-16,8)
	surface.DrawRect(x,y+8,w,h-8)
	surface.SetTexture(lclib.tex_corner8)
	surface.DrawTexturedRectRotated(x+4,y+4,8,8,0)
	surface.DrawTexturedRectRotated(x+w-4,y+4,8,8,270)
end

//char eval
lclib.evalChar = function(char) //char is a table
	local char1 = char[#char]
	local cap
	local modsrc = {
		[79]="shift",
		[80]="rshift",
		[81]="alt",
		[82]="ralt",
		[83]="ctrl",
		[84]="rctrl",
	}
	local modout = {}
	for k,v in pairs(char) do
		if v == 79 or v == 80 then
			cap = true
		end
		if v >= 79 and v <= 84 then
			modout[modsrc[v]] = true
		end
	end
	
	if input.IsKeyDown(79) or input.IsKeyDown(80) then
		cap = true
	end
	
	if not cap and (char1 >= 11 and char1 <= 36) then
		char1 = string.format("%c",char1+86)
	elseif cap then
		if char1 >= 11 and char1 <= 36 then
			char1 = string.format("%c",char1+54)
		else
			char1 = ({
				[0]="KP5",
				[1]=")",
				[2]="!",
				[3]="@",
				[4]="#",
				[5]="$",
				[6]="%",
				[7]="^",
				[8]="&",
				[9]="*",
				[10]="(",
				[47]="/",
				[48]="*",
				[49]="-",
				[50]="+",
				[52]=".",
				[53]="{",
				[54]="}",
				[55]=":",
				[56]='"',
				[58]="<",
				[59]=">",
				[60]="?",
				[61]="|",
				[62]="_",
				[63]="+",
				[64]="\n",
				[65]=" ",
				[66]="backspace",
				[67]="\t",
				[72]="insert",
				[73]="delete",
				[74]="home",
				[75]="end",
				[76]="pageup",
				[77]="pagedown",
				[80]="rshift",
				[81]="alt",
				[82]="ralt",
				[83]="ctrl",
				[84]="rctrl",
				[87]="menu",
				[88]="dU",
				[89]="dL",
				[90]="dD",
				[91]="dR",
				
			})[char1]
			/*
			if not char1 then
				char1 = nil
			end
			*/
		end
	elseif char1 >= 1 and char1 <= 10 then
		char1 = char1 - 1
	elseif char1 >= 37 and char1 <= 46 then
		char1 = char1 - 37
	elseif char1 >= 92 and char1 <= 103 then
		char1 = "F"..(char1 - 91)
	else
		char1 = ({
			[0]="KP5",
			[47]="/",
			[48]="*",
			[49]="-",
			[50]="+",
			[52]=".",
			[53]="[",
			[54]="]",
			[55]=";",
			[56]="'",
			[58]=",",
			[59]=".",
			[60]="/",
			[61]=[[\]],
			[62]="-",
			[63]="=",
			[64]="\n",
			[65]=" ",
			[66]="backspace",
			[67]="\t",
			[72]="insert",
			[73]="delete",
			[74]="home",
			[75]="end",
			[76]="pageup",
			[77]="pagedown",
			[80]="rshift",
			[81]="alt",
			[82]="ralt",
			[83]="ctrl",
			[84]="rctrl",
			[87]="menu",
			[88]="dU",
			[89]="dL",
			[90]="dD",
			[91]="dR",
		})[char1]
		/*
		if not char1 then
			char1 = nil
		end
		*/
	end
	
	if char1 then
		if char1 == 79 then
			char1 = "shift"
		elseif char1 == 80 then
			char1 = "rshift"
		end
	end
	
	char1 = tostring(char1)
	printable = #char1 == 1
	//Msg(char1,"\n")
	
	return {
		key = char1,
		mod = modout,
		printable = printable,
		last = CurTime(),
	}
end

//Overrides

local surface_meta = {
	__index = function(self,k)
		return surface[k]
	end,
}

local surface = {
	SetDrawColor = function(...)
		if type(arg[1]) == "string" then
			local col = lclib.colors[arg[1]].color
			if type(arg[2]) == "number" then
				return _G.surface.SetDrawColor(col.r,col.g,col.b,arg[2])
			else
				return _G.surface.SetDrawColor(col.r,col.g,col.b,255)
			end
		elseif type(arg[1]) == "number" then
			return _G.surface.SetDrawColor(unpack(arg))
		elseif type(arg[1]) == "table" then
			if type(arg[2]) == "number" then
				return _G.surface.SetDrawColor(arg[1].r,arg[1].g,arg[1].b,arg[2])
			else
				return _G.surface.SetDrawColor(arg[1].r,arg[1].g,arg[1].b,arg[1].a)
			end
		end
		
		return _G.surface.SetDrawColor(unpack(arg))
	end
}
setmetatable(surface,surface_meta)

local Color = function(...)
	if type(arg[1]) == "string" then
		local col = lclib.colors[arg[1]].color
		if type(arg[2]) == "number" then
			return _G.Color(col.r,col.g,col.b,arg[2])
		else
			return _G.Color(col.r,col.g,col.b,255)
		end
	elseif type(arg[1]) == "number" then
		return _G.Color(unpack(arg))
	elseif type(arg[1]) == "table" then
		if type(arg[2]) == "number" then
			return _G.Color(arg[1].r,arg[1].g,arg[1].b,arg[2])
		else
			return _G.Color(arg[1].r,arg[1].g,arg[1].b,arg[1].a)
		end
	end
	
	return _G.Color(unpack(arg))
end

//textEdit object
lclib.textEdit = function(self,args)
	local ret = {}
	ret.type = "textEdit"
	ret.contents = {}
	ret.contents[1] = ""
	ret.cache = {}
	ret.cache.numvlines = 1
	ret.cache[1] = {}
	ret.cache[1].vline = 1
	ret.cache[1][1] = {}
	ret.cache[1][1].start = 0
	ret.cache[1][1].text = ""
	ret.last = CurTime()
	ret.pos = 0
	ret.line = 1
	ret.hpos = nil
	ret.hline = nil
	
	if args then
		ret.multiline = args.multiline or false
		ret.tabs = args.tabs or false
		if args.maxchars == false then
			ret.maxchars = false
		else
			ret.maxchars = args.maxchars or 256
		end
		ret.scroll = args.scroll or false
		ret.w = args.w or nil
		ret.wrap = args.wrap or false
		ret.write = args.write == nil and true or args.write
	end
	
	ret.calcCache = function(edit,line)
		if not line then
			edit.cache = {}
			for i = 1,#edit.contents do
				edit:calcCache(i)
			end
			
			return
		end
		
		//Get starting virtual line cache point
		local vline
		if line == 1 then
			vline = 1
		else
			vline = edit.cache[line-1].vline + #edit.cache[line-1]
		end
		
		if edit.cache[line] then
			edit.cache[line].vline = nil
		end
		
		
		//Continue
		
		if not edit.contents[line] then
			edit.cache[line] = nil
			return
		end
		
		local ts = 5
		local v = edit.contents[line]
		
		edit.cache[line] = {}
		
		local px = 0
		i = 0
		local start = 0
		local dat = {}
		dat.start = 0
		repeat
			start = start+1
			i = i+1
			local val = v:sub(i,i)
			if val == "\t" then
				v = v:sub(1,i-1)..string.rep(" ",5-px%ts)..v:sub(i+1)
				start = start-4
			end
			px = px+1
			
			if edit.wrap and px >= edit.w then
				dat.text = v:sub(1,i)
				table.insert(edit.cache[line],dat)
				dat = {}
				dat.start = start
				start = start-5
				v = "     "..v:sub(i+1)
				i = 0
				px = 0
			end
		until i >= #v or i > 10000
		
		dat.text = v
		table.insert(edit.cache[line],dat)
		edit.cache[line].vline = vline
		
		for i = line+1,#edit.cache do
			edit.cache[i].vline = edit.cache[i-1].vline + #edit.cache[i-1]
		end
		
		edit.cache.numvlines = edit.cache[#edit.cache].vline + #edit.cache[#edit.cache]
	end
	
	ret.GetText = function(edit)
		return table.concat(edit.contents,"\n") or ""
	end
	
	ret.GetLength = function(edit)
		local len = 0
		for k,v in ipairs(edit.contents) do
			len = len + #v
			if k > 1 then
				len = len + 1
			end
		end
		return len
	end
	
	ret.SetText = function(edit,text,noundo)
		edit.contents = string.Explode("\n",text)
		edit.pos = #edit.contents[#edit.contents]
		edit.line = #edit.contents
		
		edit:calcCache()
		if not noundo then
			edit:undo()
			edit:undo(0)
		end
	end
	
	ret.Draw = function(edit,m,x,y,w,h,font,colbg,coltext)
		local w = w
		if edit.scroll then
			w = w-20
		end
		
		draw.RoundedBox(8,x,y,w,h,colbg and Color(colbg) or Color("edit_background",191))
		local tcol = coltext and Color(coltext) or Color("edit_text",255)
		local disp = edit:GetText()
		
		//Assumes mono-sized font
		surface.SetFont(font or "LCEdit16")
		local tw,th = surface.GetTextSize("A")
		
		//We have to replace tabs with spaces manually (Not anymore)
		local ts = 5
		
		edit.scrollpos = edit.scrollpos or 1
		local maxdisp = math.floor(h/th)
		edit.maxdisp = maxdisp
		local ln = 0
		
		//Draw highlight
		if edit.hpos and edit.hline then
			surface.SetDrawColor(0,0,255,127)
			edit:drawHighlight(x,y,w,h,edit.pos,edit.line,edit.hpos,edit.hline)
		end
		
		//Recalculate current line
		local line,metaline = edit:GetScrollLine(edit.scrollpos)
		repeat
			local v = edit.cache[line]
			if not v then
				break
			end
			vm = v[metaline]
			if not vm then
				break
			end
			ln = ln+1
			
			draw.DrawText(vm.text,font or "LCEdit16",x,y+(ln-1)*th,tcol,0)
			if metaline > 1 then
				draw.DrawText(" >=>",font or "LCEdit16",x,y+(ln-1)*th,Color(255,0,0,255),0)
			end
			
			metaline = metaline + 1
			if not v[metaline] then
				metaline = 1
				line = line+1
			end
		until ln > edit.maxdisp or ln > 10000
		
		
		//If we have been clicked, move the cursor appropriately
		if lclib.inRectBoundsWE(m.x,m.y,x,y,w,h) then
			local modShift = input.IsKeyDown(79) or input.IsKeyDown(80)
			
			if m.c[0] == 1 then
				m.dat = {edit}
				m.c[0] = 2
				
				local nx,ny = math.Round((m.x-x)/tw),math.floor((m.y-y)/th)
				//edit:SetVirtualGridPos(nx,ny+1,true)
				
				if not modShift then
					edit.pos,edit.line = edit:screenToPos(nx,ny)
					edit.hpos,edit.hline = nil,nil
					edit:updatePos()
				else
					if not (edit.hpos and edit.hline) then
						edit.hpos,edit.hline = edit.pos,edit.line
					end
					edit.pos,edit.line = edit:screenToPos(nx,ny)
					edit:updatePos()
				end
			elseif m.c[0] == 2 and m.dat[1] == edit then
				if not (edit.hpos and edit.hline) then
					edit.hpos,edit.hline = edit.pos,edit.line
				end
				local nx,ny = math.Round((m.x-x)/tw),math.floor((m.y-y)/th)
				edit.pos,edit.line = edit:screenToPos(nx,ny)
				edit:updatePos(true)
			elseif m.c[0] == -1 and m.dat[1] == edit then
				if edit.hpos == edit.pos and edit.hline == edit.line then
					edit.hpos,edit.hline = nil,nil
				end
			end
		end
		
		//Place the caret appropriately
		local pos,line = edit:GetPos()
		pos,line = edit:GetVLinePos(pos,line)
		
		if line >= edit.scrollpos and line <= edit.scrollpos+edit.maxdisp and (CurTime()-edit.last)*2%2 < 1 then
			surface.SetDrawColor(tcol)
			if not edit.multiline then
				surface.DrawRect(x+tw*pos+0,y+2,2,th-4)
			else
				surface.DrawRect(x+tw*pos+0,y+2+th*(line-edit.scrollpos),2,th-4)
				//draw.DrawText(tostring(pos)..":"..tostring(line),"Trebuchet24",x,y,Color(255,0,0,255))
			end
		end
		
		edit.lastreturn = false
		edit:TakeKey(self.key)
		
		if edit.scroll then
			w = w+20 //Revert
		end
		
		//Scrollbar
		local numlines = edit.cache.numvlines
		
		if edit.scroll then
			//local dat = self.luachipactiondata
			local x = x+w-20
			local w = 20
			draw.RoundedBox(8,x,y,w,h,Color("panel",191))
			
			//Up
			local mh = lclib.inRectBoundsWE(m.x,m.y,x,y,20,20)
			local col = mh and "button_highlight" or "button_background"
			if mh then
				if m.c[0] == 1 then
					m.dat = {edit,"scrup"}
					m.c[0] = 2
				elseif m.c[0] == 2 and m.dat[1] == edit and m.dat[2] == "scrup" then
					col = "button_press"
				elseif m.c[0] == -1 and m.dat[1] == edit and m.dat[2] == "scrup" then
					edit.scrollpos = edit.scrollpos - 3
				end
			end
			draw.RoundedBox(8,x,y,20,20,Color(col,191))
			
			//Down
			local mh = lclib.inRectBoundsWE(m.x,m.y,x,y+h-20,20,20)
			local col = mh and "button_highlight" or "button_background"
			if mh then
				if m.c[0] == 1 then
					m.dat = {edit,"scrdn"}
					m.c[0] = 2
				elseif m.c[0] == 2 and m.dat[1] == edit and m.dat[2] == "scrdn" then
					col = "button_press"
				elseif m.c[0] == -1 and m.dat[1] == edit and m.dat[2] == "scrdn" then
					edit.scrollpos = edit.scrollpos + 3
				end
			end
			draw.RoundedBox(8,x,y+h-20,20,20,Color(col,191))
			
			//Pixel dimensions
			local sbpixlineh = th
			local sbpixspace = h-40
			
			//Line dimensions
			local sbnumline = edit.scrollpos or 1
			local sbvnumline = edit:GetScrollLine(edit.scrollpos) or 1
			local sbnumlines = numlines+edit.maxdisp-2 //So we can scroll below our code
			local sbnumspace = math.floor(h/th)
			
			//Clamp scrollbar and scroll by wheel
			edit.scrollpos = math.Clamp(math.Round(sbnumline-m.c.wheel),1,math.max(sbnumlines-sbnumspace+1,1))
			
			//Recalculate current line
			sbnumline = edit.scrollpos
			sbvnumline = edit:GetScrollLine(edit.scrollpos) or 1
			
			
			//Find pixel position/height
			local sbpixline = (sbnumline-1)/sbnumlines*sbpixspace
			local sbpixheight = math.min(sbnumspace/sbnumlines*sbpixspace,sbpixspace)
			
			//Scrollbar clicking
			local mh = lclib.inRectBoundsWE(m.x,m.y,x,y+20+sbpixline,20,sbpixheight)
			local col = mh and "button_highlight" or "button_background"
			if mh then
				if m.c[0] == 1 then
					m.dat = {edit,"scrmi",m.y-(y+sbpixline)}
					m.c[0] = 2
				elseif m.c[0] == -1 and m.dat[1] == edit and m.dat[2] == "scrmi" then
				end
			end
			if m.c[0] == 2 and m.dat[1] == edit and m.dat[2] == "scrmi" then
				local pixpos = m.y-m.dat[3]-y
				edit.scrollpos = math.Clamp(math.floor(pixpos/sbpixspace*sbnumlines),1,math.max(sbnumlines-sbnumspace+1,1))
				col = "button_press"
			end
			
			draw.RoundedBox(8,x,y+20+sbpixline,20,sbpixheight,Color(col,191))
			
		end
	end
	
	ret.GetPos = function(edit)
		return edit.pos,edit.line
	end
	
	ret.GetScrollLine = function(edit,y)
		local line = 0
		local vline = 0
		local metaline
		local fin = false
		for k,v in ipairs(edit.cache) do
			metaline = 0
			line = line+1
			for i,o in ipairs(v) do
				vline = vline + 1
				metaline = metaline + 1
				if vline >= y then
					fin = true
					break
				end
			end
			if fin then
				break
			end
		end
		
		return line,metaline
	end
	
	ret.GetVLinePos = function(edit,x,y)
		local ts = 5
		local px = 0
		local py = edit.cache[y].vline or y
		
		local off = 0
		local indent = false
		if edit.wrap then
			for i = #edit.cache[y],1,-1 do
				if not edit.cache[y][i].start then
					break
				end
				if x >= edit.cache[y][i].start then
					py = py+i-1
					off = edit.cache[y][i].start
					indent = i > 1
					break
				end
			end
		end
		
		indent = indent and 5 or 0
		
		for i = off,x do
			local val = (edit.contents[y] or ""):sub(i,i)
			
			if val == "\t" then
				px = px+5-(px-1)%ts
			else
				px = px+1
			end
		end
		
		return px+indent-1,py
	end
	
	ret.GetLinePos = function(edit,x,y)
		local ts = 5
		local px = 0
		local py = y
		
		local off = 0
		local indent = false
		
		indent = indent and 5 or 0
		
		for i = 1,x do
			local val = (edit.contents[y] or ""):sub(i,i)
			
			if val == "\t" then
				px = px+5-px%ts
			else
				px = px+1
			end
		end
		
		return px-off+indent,py
	end
	
	ret.GetALinePos = function(edit,x,y)
		if not edit.wrap then
			return edit:GetLinePos(x,y)
		end
		
		return x,y
	end
	
	//TODO: Make cache with tab > space replacement
	
	ret.SetVirtualGridPos = function(edit,x,y,immediate)
		local last = 1
		for k,v in ipairs(edit.cache) do
			if v.vline > y then
				break
			end
			last = k
		end
		
		edit:SetGridPos(x,last,immediate)
	end
	
	ret.SetGridPos = function(edit,x,y,immediate)
		if not edit.wrap then
			return ret.SetGridPosRaw(edit,x,y,immediate)
		end
		
		local vpos = edit.cache[y].start
		local y = y+edit.scrollpos-1
		
		local x,y = edit:GetALinePos(x,y)
		
		return ret.SetGridPosRaw(edit,x,y,immediate)
	end
	
	ret.SetGridPosRaw = function(edit,x,y,immediate)
		local ts = 5
		local y = y//+edit.scrollpos-1
		local px,py = 0,y
		
		if ret:GetLength() > 0 and not (x <= 0 and y <= 0) then
			if edit.contents[y] then
				for i = 1,#edit.contents[y] do
					if px >= x then
						px = math.min(i-1,#edit.contents[y])
						py = y
						break
					end
					
					local val = edit.contents[y]:sub(i,i)
					if val == "\t" then
						px = px+(5-px%ts)
					else
						px = px+1
					end
				end
			else
				px = #edit.contents[#edit.contents]
				py = #edit.contents
			end
		else
		end
		
		py = math.Clamp(py,1,#edit.contents)
		px = math.Clamp(px,0,#edit.contents[py])
		
		if immediate then
			edit.last = CurTime()
			edit.pos = px
			edit.line = py
		end
		
		return px,py
	end
	
	ret.drawHighlight = function(edit,x,y,w,h,spos,sline,hpos,hline)
		local font = false
		
		if hline < sline or (hline == sline and hpos < spos) then
			edit:drawHighlight(x,y,w,h,hpos,hline,spos,sline)
			return
		end
		
		//Assumes mono-sized font
		surface.SetFont(font or "LCEdit16")
		local tw,th = surface.GetTextSize("A")
		local ts = 5
		
		for aline = sline,hline do
			local p1 = 0
			local p2 = #edit.contents[aline]
			
			if aline == sline then
				p1 = spos
			end
			if aline == hline then
				p2 = hpos
			end
			
			local p1x,p1y = edit:posToGrid(p1,aline)
			local p2x,p2y = edit:posToGrid(p2,aline)
			
			for vline = p1y,p2y do
				if vline >= edit.scrollpos and vline <= edit.scrollpos+edit.maxdisp then
					local p1x = p1x
					local p2x = p2x+1
					
					if vline ~= p1y then
						p1x = ts
					end
					if vline ~= p2y then
						p2x = edit.w+1
					end
					
					local a = x+tw*p1x+0
					local b = y+th*(vline-edit.scrollpos)
					local c = tw*p2x-a
					local d = th
					surface.DrawRect(a,b,c,d)
				end
			end
		end
	end
	
	ret.screenToPos = function(edit,x,y)
		return edit:gridToPos(x,y+edit.scrollpos)
	end
	
	ret.posToGrid = function(edit,x,y)
		pos,line = edit:GetVLinePos(x,y)
		return pos,line
	end
	
	ret.gridToPos = function(edit,x,y,invydir)
		local pos,line = 0,1
		
		local lastline = 1
		local vline = 1
		local mline = 1
		for k,v in ipairs(edit.cache) do
			if v.vline > y then
				vline = lastline
				mline = y-vline+1
				break
			end
			lastline = v.vline
			line = k
		end
		
		if mline > 1 and x < 5 then
			if not invydir and edit.contents[line+1]  then
				line = line + 1
				vline = vline + #edit.cache[line] + 1
				mline = 1
			elseif invydir then
				vline = vline-mline+1
				mline = 1
			end 
		end
		
		//PrintTable(edit.cache)
		
		local curline = edit.cache[line]
		local curmline = curline[mline]
		
		line = line
		local curaline = edit.contents[line]
		pos = 0
		
		local i = curmline.start //Where it is at in contents
		local vx = 0 //Where it is at in cache
		local crash = 0
		local fin = false
		if x ~= 0 then
			repeat
				crash = crash + 1
				i = i+1
				local chr = curaline:sub(i,i)
				if chr == "\t" then
					local tab = (5-vx%5)
					if tab + vx > x then
						i = i-1
						fin = true
					end
					if not fin then
						vx = vx + tab
					end
				else
					vx = vx+1
				end
			until fin or vx >= x or crash > 10000
		end
		
		if mline > 1 then
			pos = i - 5
		else
			pos = i
		end
		
		return pos,line
	end
	
	ret.updatePos = function(edit,nolast)
		local bottom = false
		if edit.line > #edit.contents then
			bottom = true
		end
		edit.line = math.Clamp(edit.line,1,#edit.contents)
		if not bottom then
			edit.pos = math.Clamp(edit.pos,0,#edit.contents[edit.line])
		else
			edit.pos = #edit.contents[edit.line]
		end
		if not nolast then
			edit.last = CurTime()
		end
	end
	
	ret.updateHPos = function(edit)
		local bottom = false
		if edit.hline > #edit.contents then
			bottom = true
		end
		edit.hline = math.Clamp(edit.hline,1,#edit.contents)
		if not bottom then
			edit.hpos = math.Clamp(edit.hpos,0,#edit.contents[edit.hline])
		else
			edit.hpos = #edit.contents[edit.hline]
		end
	end
	
	ret.GetReturn = function(edit)
		return edit.lastreturn
	end
	
	ret.makeCacheEntry = function(edit)
		local dat = {}
		dat[1] = {}
		dat[1].text = ""
		return dat
	end
	
	ret.tabSelection = function(edit,spos,sline,hpos,hline)
		if not spos then
			edit:tabSelection(edit.pos,edit.line,edit.hpos,edit.hline)
			return
		end
		if not (hpos and hline) then
			return
		end
		local dir = sline < hline and 1 or -1
		/*
		if hline < sline or (hline == sline and hpos < spos) then
			edit:tabSelection(hpos,hline,spos,sline)
			return
		end
		*/
		
		local line = sline
		for iteration = sline,hline,dir do
			local p1x = 0
			local p2x = #edit.contents[line]
			
			if line == sline then
				p1x = spos
			end
			/*
			if line == hline then
				p2x = hpos
			end
			*/
			
			if not (p2x == 0 and (line == hline or line == sline)) then
				edit.contents[line] = "\t"..edit.contents[line]
				edit:calcCache(line)
			end
			
			if p2x > 0 and line == edit.line then
				edit.pos = edit.pos + 1
			end
			if p2x > 0 and line == edit.hline then
				edit.hpos = edit.hpos + 1
			end
			
			line = line+dir
		end
	end
	ret.untabSelection = function(edit,spos,sline,hpos,hline)
		if not spos then
			edit:untabSelection(edit.pos,edit.line,edit.hpos,edit.hline)
			return
		end
		if not (hpos and hline) then
			return
		end
		local dir = sline < hline and 1 or -1
		/*
		if hline < sline or (hline == sline and hpos < spos) then
			edit:untabSelection(hpos,hline,spos,sline)
			return
		end
		*/
		
		local line = sline
		for iteration = sline,hline,dir do
			local p1x = 0
			local p2x = #edit.contents[line]
			
			if line == sline then
				p1x = spos
			end
			if line == hline then
				p2x = hpos
			end
			
			if p2x > 0 and line == edit.line and edit.contents[line]:sub(1,1) == "\t" then
				edit.pos = edit.pos - 1
			end
			if p2x > 0 and line == edit.hline and edit.contents[line]:sub(1,1) == "\t" then
				edit.hpos = edit.hpos - 1
			end
			if not (p2x == 0 and (line == hline or line == sline)) then
				if edit.contents[line]:sub(1,1) == "\t" then
					edit.contents[line] = edit.contents[line]:sub(2)
					edit:calcCache(line)
				end
			end
			
			line = line+dir
		end
	end
	ret.deleteSelection = function(edit,spos,sline,hpos,hline)
		if not spos then
			edit:deleteSelection(edit.pos,edit.line,edit.hpos,edit.hline)
			return
		end
		if not (hpos and hline) then
			return
		end
		if hline < sline or (hline == sline and hpos < spos) then
			edit:deleteSelection(hpos,hline,spos,sline)
			return
		end
		
		local line = sline
		local tostack = false
		for iteration = sline,hline do
			local p1x = 0
			local p2x = #edit.contents[line]
			
			if iteration == sline then
				p1x = spos
			end
			if iteration == hline then
				p2x = hpos
			end
			
			if p1x > 0 and iteration == sline and hline > sline then
				tostack = true
				line = line + 1
			elseif p1x == 0 and p2x >= #edit.contents[line] and iteration ~= hline then
				table.remove(edit.contents,line)
				table.remove(edit.cache,line)
				edit:calcCache(line)
			/*
			elseif p2x >= #edit.contents[line] and iteration ~= hline then
				edit.contents[line] = edit.contents[line]:sub(1,math.max(0,p1x))..table.remove(edit.contents,line+1)
				table.remove(edit.cache,line+1)
				edit:calcCache(line)
				line = line + 1
			*/
			else
				edit.contents[line] = edit.contents[line]:sub(1,math.max(0,p1x))..edit.contents[line]:sub(p2x+1)
				edit:calcCache(line)
				line = line + 1
			end
			edit.pos = spos
			edit.line = sline
			
			edit.hpos,edit.hline = nil,nil
		end
		
		if tostack and edit.contents[sline+1] then
			edit.contents[sline] = edit.contents[sline]:sub(1,spos)..table.remove(edit.contents,sline+1)
			table.remove(edit.cache,sline+1)
			edit:calcCache(sline)
		end
	end
	
	ret.getSelected = function(edit,spos,sline,hpos,hline)
		if not spos then
			return edit:getSelected(edit.pos,edit.line,edit.hpos,edit.hline)
		end
		if not (hpos and hline) then
			return
		end
		if hline < sline or (hline == sline and hpos < spos) then
			return edit:getSelected(hpos,hline,spos,sline)
		end
		
		local out = ""
		for line = sline,hline do
			local p1x = 1
			local p2x = #edit.contents[line]
			
			if line == sline then
				p1x = spos+1
			end
			if line == hline then
				p2x = hpos
			end
			
			out = out..edit.contents[line]:sub(p1x,p2x)
			if line < hline then
				out = out.."\n"
			end
		end
		
		return out
	end
	
	ret.undos = {}
	ret.curdo = nil
	ret.undo = function(edit,type)
		if not type then
			edit.undos = {}
			edit.curdo = nil
		elseif type == true then
			//Change branch
			if edit.curdo then
				for i = edit.curdo+1,#edit.undos do
					edit.undos[#edit.undos] = nil
				end
				edit.curdo = nil
			end
		elseif type == 0 then
			//Store
			if edit.curdo then
				for i = edit.curdo+1,#edit.undos do
					edit.undos[#edit.undos] = nil
				end
				edit.curdo = nil
			end
			
			edit.undos[#edit.undos+1] = {
				pos = edit.pos,
				line = edit.line,
				text = edit:GetText(),
				lastdel = edit.lastdel,
			}
			if #edit.undos > 256 then
				table.remove(edit.undos,1)
			end
		elseif type == -1 then
			//Undo
			if not edit.curdo then
				edit:undo(0)
				edit.curdo = #edit.undos
			end
			
			if edit.undos[edit.curdo-1] then
				edit.curdo = edit.curdo - 1
				local dat = edit.undos[edit.curdo]
				edit:SetText(dat.text,true)
				edit.line = dat.line
				edit.pos = dat.pos
				edit.lastdel = dat.lastdel
				edit:updatePos()
			end
		elseif type == 1 then
			//Redo
			if edit.curdo and edit.undos[edit.curdo+1] then
				edit.curdo = edit.curdo + 1
				local dat = edit.undos[edit.curdo]
				edit:SetText(dat.text,true)
				edit.line = dat.line
				edit.pos = dat.pos
				edit.lastdel = dat.lastdel
				edit:updatePos()
			end
		end
	end
	
	ret.lastdel = nil
	ret.TakeKey = function(edit,key) //TAKE THIS, EAT SHIT!
		if not key then
			return
		end
		
		local noclamp = false
		local noundo = true
		
		local modShift = input.IsKeyDown(79) or input.IsKeyDown(80)
		local modCtrl = input.IsKeyDown(83) or input.IsKeyDown(84)
		
		local pos,line = edit:GetPos()
		
		local noupd = false
		if modCtrl and key.printable then
			if edit.write then
				if key.key == "x" then
					edit:undo(0)
					edit.lastdel = nil
					
					edit.clipboard = edit:getSelected()
					edit:deleteSelection()
				elseif key.key == "c" then
					edit.clipboard = edit:getSelected()
				elseif key.key == "v" then
					if edit.clipboard then
						edit:undo(0)
						edit.lastdel = nil
						
						edit:deleteSelection()
						
						local npos,nline,nfin = edit.pos,edit.line,false
						
						local dat = string.Explode("\n",edit.clipboard)
						if #dat >= 2 then
							table.insert(edit.contents,edit.line+1,dat[#dat]..edit.contents[edit.line]:sub(edit.pos+1))
							table.insert(edit.cache,edit.line+1,edit:makeCacheEntry())
							edit.contents[edit.line] = edit.contents[edit.line]:sub(1,edit.pos)
							edit:calcCache(edit.line+1)
							
							npos,nline,nfin = #dat[#dat],edit.line+#dat-1,true
						end
						if #dat >= 1 then
							edit.contents[edit.line] = edit.contents[edit.line]:sub(1,edit.pos)..dat[1]..edit.contents[edit.line]:sub(edit.pos+1)
							
							if not nfin then
								npos = edit.pos+#dat[1]
							end
							
							edit:calcCache(edit.line)
						end
						if #dat >= 3 then
							for i = #dat-1,2,-1 do
								table.insert(edit.contents,edit.line+1,dat[i])
								table.insert(edit.cache,edit.line+1,edit:makeCacheEntry())
								edit:calcCache(edit.line+1)
							end
						end
						
						edit.pos,edit.line = npos,nline
					end
				elseif key.key == "a" then
					edit.line = #edit.contents
					edit.pos = #edit.contents[edit.line]
					edit.hline = 1
					edit.hpos = 0
					
					noclamp = true
				elseif key.key == "z" then
					edit:undo(-1)
					noundo = true
				elseif key.key == "y" then
					edit:undo(1)
					noundo = true
				end
			end
		elseif key.printable then
			if edit.write then
				local fin = false
				if edit.multiline or key.key ~= "\n" then
					if edit.tabs and key.key == "\t" and edit.hpos and edit.hline ~= edit.line then
						if not modShift then
							edit:tabSelection()
						else
							edit:untabSelection()
						end
						fin = true
					end
					
					if not fin then
						edit:deleteSelection()
						pos,line = edit:GetPos()
					end
				end
				
				if key.key == "\n" and not edit.multiline then
					edit.lastreturn = true
					return
				end
				
				edit:undo(true)
				if edit.lastdel then
					edit:undo(0)
					edit.lastdel = false
				end
				
				if key.key == "\n" then
					table.insert(edit.contents,edit.line+1,edit.contents[edit.line]:sub(edit.pos+1))
					table.insert(edit.cache,edit.line+1,edit:makeCacheEntry())
					edit.contents[edit.line] = edit.contents[edit.line]:sub(1,edit.pos)
					local exp = string.Explode("",edit.contents[edit.line])
					edit.pos = 0
					edit:calcCache(edit.line)
					edit.line = edit.line + 1
					
					if edit.tabs then
						local count = 0
						for k,v in ipairs(exp) do
							if v == "\t" then
								count = count+1
							else
								break
							end
						end
						
						edit.pos = count
						edit.contents[edit.line] = string.rep("\t",count) .. edit.contents[edit.line]
					end
					
					edit:calcCache(edit.line)
					
					fin = true
				end
				
				if not fin then
					if not edit.tabs and key.key == "\t" then
						return
					end
					
					edit.pos = edit.pos + 1
					edit.contents[line] = edit.contents[line]:sub(1,math.max(0,pos))..key.key..edit.contents[line]:sub(pos+1)
					edit:calcCache(line)
				end
			end
		elseif key.key == "backspace" then
			if edit.write then
				edit:undo(true)
				if edit.lastdel ~= false then
					edit:undo(0)
					edit.lastdel = true
				end
				
				if edit.hpos and edit.hline then
					edit:deleteSelection()
				else
					if pos > 0 then
						edit.contents[line] = edit.contents[line]:sub(1,math.max(0,pos-1))..edit.contents[line]:sub(pos+1)
						edit.pos = edit.pos - 1
						edit:calcCache(line)
					elseif line > 1 then
						edit.pos = #edit.contents[line-1]
						edit.contents[line-1] = edit.contents[line-1]..table.remove(edit.contents,line)
						table.remove(edit.cache,line)
						edit:calcCache(edit.line)
						edit.line = edit.line-1
						edit:calcCache(edit.line)
					end
				end
			end
		elseif key.key == "delete" then
			if edit.write then
				edit:undo(true)
				if edit.lastdel ~= false then
					edit:undo(0)
					edit.lastdel = true
				end
				
				if edit.hpos and edit.hline then
					edit:deleteSelection()
				else
					local linelen = #edit.contents[line]
					if pos < linelen then
						edit.contents[line] = edit.contents[line]:sub(1,math.max(0,pos))..edit.contents[line]:sub(pos+2)
						edit:calcCache(line)
					elseif line < #edit.contents then
						edit.contents[line] = edit.contents[line]..table.remove(edit.contents,line+1)
						table.remove(edit.cache,line+1)
						edit:calcCache(line)
						edit:calcCache(line+1)
					end
				end
			end
		elseif key.key:sub(1,1) == "d" then
			noundo = true
			local dir = key.key:sub(2,2)
			
			if not modShift then
				edit.hpos,edit.hline = nil,nil
			elseif not edit.hpos and not edit.hline then
				edit.hpos,edit.hline = edit.pos,edit.line
			end
			
			if not edit.multiline then
				local hor = dir == "R" and 1 or (dir == "L" and -1 or 0)
				edit.pos = edit.pos+hor
				
				//Quick move
				if hor ~= 0 and modCtrl then
					local delta = 0
					local n = hor < 0 and edit.pos or edit.pos + 1
					local chr = edit.contents[edit.line]:sub(n,n)
					local white = chr == "" or luachip.charIsAlpha(chr) or tonumber(chr)
					for i = hor < 0 and edit.pos or edit.pos+1,hor < 0 and (1) or (#edit.contents[edit.line]),hor do
						local chr = edit.contents[edit.line]:sub(i,i)
						if chr ~= "" then
							if white then
								if not (luachip.charIsAlpha(chr) or tonumber(chr)) then
									break
								end
							else
								if luachip.charIsAlpha(chr) or tonumber(chr) then
									break
								end
							end
						end
						delta = delta + hor
					end
					if delta == 0 then
						delta = hor
					end
					hor = delta
				end
				//End quick move
			else
				local hor = dir == "R" and 1 or (dir == "L" and -1 or 0)
				local ver = dir == "D" and 1 or (dir == "U" and -1 or 0)
				
				//Quick move
				if hor ~= 0 and modCtrl then
					local delta = 0
					local n = hor < 0 and edit.pos or edit.pos + 1
					local chr = edit.contents[edit.line]:sub(n,n)
					local white = chr == "" or luachip.charIsAlpha(chr) or tonumber(chr)
					for i = hor < 0 and edit.pos or edit.pos+1,hor < 0 and (1) or (#edit.contents[edit.line]),hor do
						local chr = edit.contents[edit.line]:sub(i,i)
						if chr ~= "" then
							if white then
								if not (luachip.charIsAlpha(chr) or tonumber(chr)) then
									break
								end
							else
								if luachip.charIsAlpha(chr) or tonumber(chr) then
									break
								end
							end
						end
						delta = delta + hor
					end
					if delta == 0 then
						delta = hor
					end
					hor = delta
				end
				//End quick move
				
				//Move line
				if edit.write then
					local fin = false
					if ver ~= 0 and modCtrl and modShift then
						edit:undo(0)
						edit.hpos,edit.hline = nil,nil
						if ver > 0 then
							if edit.line < #edit.contents then
								local a = edit.contents[edit.line]
								edit.contents[edit.line] = edit.contents[edit.line+1]
								edit.contents[edit.line+1] = a
								edit.line = edit.line+1
								edit:calcCache(line)
								edit:calcCache(line+1)
							end
						else
							if edit.line > 1 then
								local a = edit.contents[edit.line]
								edit.contents[edit.line] = edit.contents[edit.line-1]
								edit.contents[edit.line-1] = a
								edit.line = edit.line-1
								edit:calcCache(line)
								edit:calcCache(line-1)
							end
						end
						fin = true
						noundo = true
					elseif ver ~= 0 and modCtrl then
						//Quick scroll
						edit.scrollpos = edit.scrollpos + ver
						
						//Clamp scrollbar and scroll by wheel
						edit.scrollpos = math.Clamp(edit.scrollpos,1,edit.cache.numvlines+edit.maxdisp-2)
						
						noclamp = true
						fin = true
					end
				end
				//End quick scroll
				
				if not fin then
					if hor ~= 0 then
						edit.pos = edit.pos+hor
					end
					if edit.pos < 0 then
						edit.line = edit.line-1
						if edit.line > 0 and edit.line <= #edit.contents then
							edit.pos = #edit.contents[edit.line]
						end
					end
					if edit.contents[edit.line] and edit.pos > #edit.contents[edit.line] then
						edit.line = edit.line + 1
						edit.pos = 0
					end
					if ver ~= 0 then
						local ax,ay = edit:posToGrid(edit.pos,edit.line)
						edit.pos,edit.line = edit:gridToPos(ax,math.max(ay+ver,1),ver<0)
					end
				end
			end
		else
			noupd = true
		end
		if not noupd then
			edit.last = CurTime()
		end
		if edit.maxchars and edit.write then
			local left = edit.maxchars
			for line,str in ipairs(edit.contents) do
				if #str < left then
					left = left - #str
				else
					//Same as backspace except for left,line
					if pos > 0 then
						edit.contents[line] = edit.contents[line]:sub(1,math.max(0,left-1))..edit.contents[line]:sub(left+1)
					elseif line > 0 then
						edit.contents[line-1] = edit.contents[line-1]..table.remove(edit,line)
					end
					break
				end
				left = left - 1 //Line
			end
			edit.contents = edit.contents:sub(1,edit.maxchars)
		end
		
		local bottom = false
		if edit.line > #edit.contents then
			bottom = true
		end
		edit.line = math.Clamp(edit.line,1,#edit.contents)
		if not bottom then
			edit.pos = math.Clamp(edit.pos,0,#edit.contents[edit.line])
		else
			edit.pos = #edit.contents[edit.line]
		end
		
		//Ensure the cursor is on the screen
		if not noclamp then
			local a,min = edit:posToGrid(edit.pos,edit.line)
			edit.scrollpos = math.Clamp(edit.scrollpos,min-edit.maxdisp,min)
		end
		
		if not noundo then
			edit:undo(0)
		end
	end
	
	return ret
end

//Function
--"Function
function SWEP:DrawScreen(m,x,y,w,h)
	//Actual screen corners: (4,4) (507,507) or 4,4,503,503 x,y,w,h
	
	if self.char then
		self.key = lclib.evalChar(self.char)
		self.char = nil
	else
		self.key = nil
	end
	
	local getThrob = function(time)
		local throb = (time or UnPredictedCurTime())%2
		if throb > 1 then
			throb = 2-throb
		end
		throb = throb^2
		
		return throb
	end
	
	//Black
	surface.SetDrawColor(0,0,0,255)
	surface.DrawRect(x,y,w,h)
	
	//Cool background
	//TODO: Make this code reuse tables
	if not true then
		local throb = getThrob(UnPredictedCurTime()/10)
		local play = (1280)*throb
		surface.SetDrawColor(0,255,0,100)
		epcircle.DrawCircle(throb*1280-play-256,256,play,64,-14/throb,28/throb,32)
		
		local throb = getThrob(UnPredictedCurTime()/5)
		local play = (1280)*throb
		local ang = UnPredictedCurTime()*90%360
		local angrad = ang/180*math.pi
		surface.SetDrawColor(0,0,255,100)
		epcircle.DrawCircle(
			math.cos(angrad)*(640)+256,
			math.sin(angrad)*(640)+256,
			play,64,
			-ang+135,90,
			16
		)
	end
	
	//Title bar
	local text = "Lua Chip Menu v" .. tostring((luachip or {}).version or "0")
	surface.SetFont("Trebuchet24")
	local tw = surface.GetTextSize(text)+8
	
	do
		/*
		surface.SetDrawColor(0,0,0,255)
		surface.DrawRect(x,y,w,24)
		*/
		
		local x = x+tw+8
		local w = w-tw-8
		//News ticker
		
		local text = tostring(luachipgc_message) or ""
		local tw = tonumber(luachipgc_message_lcsweplen) or 0
		local scrollx = CurTime()*100%tw
		
		for i=0,math.ceil(w/tw) do
			draw.DrawText(text,"Trebuchet24",x+i*tw-scrollx,y+4,Color(255,255,255,255),0)
		end
		
		surface.SetTexture(lclib.tex_gradient)
		surface.SetDrawColor(0,0,0,255)
		surface.DrawTexturedRect(x,y,64,28)
		surface.DrawTexturedRect(x,y,64,28)
		surface.DrawTexturedRect(x,y,64,28)
		
		if luachipgc_outdated then
			draw.DrawText("outdated >> v"..tostring(luachipgc_version),"Trebuchet24",x+64,y+16,Color(255,0,0,200),0)
		end
	end
	
	//Draw title and version
	surface.SetDrawColor(0,0,0,255)
	surface.DrawRect(0,0,tw+8,28) //So the ticker text is hidden
	draw.DrawText(text,"Trebuchet24",8,4,Color(255,255,255,255),0)
	
	//Time bar
	draw.DrawText(tostring(os.date("%Y %B %d")),"Trebuchet24",8,h-24-4,Color(255,255,255,255),0)
	draw.DrawText(tostring(os.date("%A %I:%M:%S %p")),"Trebuchet24",w-8,h-24-4,Color(255,255,255,255),2)
	
	self.activetab = self.activetab or 1
	do //Tabs
		local x,y = x+8,y+30
		local w,h = w-16,h-60
		
		surface.SetFont("Trebuchet24")
		
		local tabs = {
			{
				label = "LuaChip",
				draw = function(x,y,w,h)
					local dat = self.luachipactiondata
					if not self.luachipactiondata then
						self.luachipactiondata = {}
						dat = self.luachipactiondata
						
						dat.Object = {
						}
						dat.Script = {
							newcontent = false,
							content = "",
						}
						dat.File = {
							directory = "luachip/",
							refresh = function()
								if not file.IsDir("luachip") then
									file.CreateDir("luachip")
								end
								
								dat.File.list = {}
								
								for k,v in pairs(file.FindDir(dat.File.directory.."*")) do
									table.insert(dat.File.list,{
										name = v,
										type = "dir",
									})
								end
								for k,v in pairs(file.Find(dat.File.directory.."*.txt")) do
									table.insert(dat.File.list,{
										name = v,
										type = ".txt",
									})
								end
							end,
						}
						dat.Link = {
							cur = nil,
						}
					end
					
					--"Object/Script/File menu code
					
					local actions = {
						{
							label = "Object",
							act = function()
							end,
							draw = function(x,y,w,h)
								local ent = self:GetNWEntity("curEnt")
								
								if not IsEntity(ent) and ent:IsValid() then
									draw.DrawText("No entity selected.","Trebuchet24",x+4,y,Color("panel_text"),0)
								else
									draw.DrawText(tostring(ent),"Trebuchet24",x+4,y,Color("panel_text"),0)
									
									y = y+24
									
									local stat,eta = lcTrans.stat("luachipswep")
									local download
									if not stat then
										download = true
										stat,eta = lcTrans.statDownload("luachipswep")
									end
									draw.RoundedBox(8,x+4,y+4,w-8,24,Color(255,255,255,191))
									if stat then
										if stat > 0 then
											draw.RoundedBox(8,x+4,y+4,(w-8)*stat,24,Color(download and 0 or 255,download and 255 or 0,0,255))
										end
										
										local text
										eta = math.Round(eta)
										if eta == 1 then
											text = "1 second remaining."
										else
											text = tostring(eta).." seconds remaining."
										end
										draw.DrawText(text,"Trebuchet24",x+w/2,y+4,Color(0,0,255,255),1)
									else
										draw.DrawText("Ready for transmission.","Trebuchet24",x+w/2,y+4,Color(0,0,255,255),1)
									end
									
									y = y+32
									
									local textSize = 40
									local mh = lclib.inBounds(m.y,y,y+textSize)
									do
										surface.SetFont("Trebuchet40")
										local tw = surface.GetTextSize("Upload")+8
										local x,y = x+4,y+4
										local w,h = tw,textSize
										local col = "button_background"
										if mh and lclib.inBoundsW(m.x,x,w) then
											col = "button_highlight"
											
											if m.c[0] == 1 then
												m.dat = {"tabobjectupload"}
												m.c[0] = 2
											elseif m.c[0] == 2 and m.dat[1] == "tabobjectupload" then
												col = "button_press"
											elseif m.c[0] == -1 and m.dat[1] == "tabobjectupload" then
												//Act for upload script
												if dat.Script.editScript then
													//Msg(dat.Script.editScript:GetText(),"\n")
													
													lcTrans.send("luachipswep","luachipswep",tostring(dat.Script.editScript:GetText()))
												end
											end
										end
										draw.RoundedBox(8,x,y,w,h,Color(col,191))
										draw.DrawText("Upload","Trebuchet40",x+tw/2,y,Color("button_text",191),1)
										
										//DIVIDE
										
										local x,y = x+tw+4,y
										local tw = surface.GetTextSize("Download")+8
										local w,h = tw,textSize
										local col = "button_background"
										if mh and lclib.inBoundsW(m.x,x,w) then
											col = "button_highlight"
											
											if m.c[0] == 1 then
												m.dat = {"tabobjectupload"}
												m.c[0] = 2
											elseif m.c[0] == 2 and m.dat[1] == "tabobjectupload" then
												col = "button_press"
											elseif m.c[0] == -1 and m.dat[1] == "tabobjectupload" then
												//Act for download script
												//Msg(dat.Script.editScript:GetText(),"\n")
												
												local f = function(str)
													if dat and dat.Script and dat.Script.editScript then
														dat.Script.editScript:SetText(str)
													end
												end
												lcTrans.setCommandFunction("luachipswep",f)
												
												RunConsoleCommand("lci","download")
											end
										end
										draw.RoundedBox(8,x,y,w,h,Color(col,191))
										draw.DrawText("Download","Trebuchet40",x+tw/2,y,Color("button_text",191),1)
									end
									
									y = y+textSize
									
									/*
									surface.SetFont("Trebuchet16")
									local tw,th = surface.GetTextSize("Test\nTest\nTest\nTest")
									local lines = math.floor((h-y)/th*4)+1
									*/
									
									local lines = 18+1
									local text = string.Explode("\n",luachipswepconsolebuffer or "[Console output not available]")
									local disp = ""
									for i = #text,#text-lines+1,-1 do
										if i > 0 then
											disp = tostring(text[i]).."\n"..disp
										end
									end
									
									draw.DrawText(disp,"Trebuchet16",x+4,y+4,Color(255,255,255,255),0)
									
								end
							end,
						},
						{
							label = "Script",
							act = function()
							end,
							draw = function(x,y,w,h)
								
								//Text field
								do
									dat.Script.editScript = dat.Script.editScript or lclib.textEdit(self,{
										multiline = true,
										tabs = true,
										maxchars = false,
										scroll = true,
										wrap = true,
										w = 59,
									})
									
									if dat.Script.newcontent then
										dat.Script.editScript:SetText(dat.Script.content)
										dat.Script.newcontent = false
									end
									
									dat.Script.editScript:Draw(m,x,y,w,h)
								end
							end,
						},
						{
							label = "File",
							act = function()
								dat.File.refresh()
							end,
							draw = function(x,y,w,h)
								//Directory bar
								
								local buttons = {
									{
										label = "Up",
										action = function(me)
											a = string.Explode("/",dat.File.directory)
											a[#a] = nil
											a[#a] = nil
											dat.File.directory = string.Implode("/",a).."/"
											dat.File.refresh()
										end,
									},
								}
								
								local dirstart = #buttons+1
								
								local dir = ""
								for k,v in pairs(string.Explode("/","data/"..dat.File.directory)) do
									if v ~= "" then
										if v ~= "data" then
											dir = dir..v.."/"
										end
										table.insert(buttons,{
											label = v,
											directory = dir,
											action = function(me)
												dat.File.directory = me.directory
												dat.File.refresh()
											end,
										})
									end
								end
								
								surface.SetFont("Trebuchet16")
								draw.RoundedBox(8,x,y,w,16,Color("panel",191))
								local wx = x+4
								local mh = lclib.inBounds(m.y,y,y+16)
								local action
								for k,v in pairs(buttons) do
									local sz = surface.GetTextSize(v.label)+8
									local mh = mh and lclib.inBoundsW(m.x,wx-4,sz)
									
									if mh then
										local col = "button_highlight"
										
										if m.c[0] == 1 then
											m.dat = {"tabfiledir",k}
											m.c[0] = 2
										elseif m.c[0] == 2 and m.dat[1] == "tabfiledir" and m.dat[2] == k then
											col = "button_press"
										elseif m.c[0] == -1 and m.dat[1] == "tabfiledir" and m.dat[2] == k then
											action = k
										end
										
										draw.RoundedBox(8,wx-4,y,sz,16,Color(col,191))
									end
									
									draw.DrawText(v.label,"Trebuchet16",wx,y,Color("button_text",191),0)
									
									if k >= dirstart then
										draw.DrawText("/","Trebuchet16",wx+sz-2,y,Color("button_text",191),2)
									end
									
									wx = wx+sz+1
								end
								if action then
									buttons[action]:action()
								end
								
								//Lower actions
								y = y+16
								h = h-16
								do
									local y = y+h-44
									local h = 44
									draw.RoundedBox(8,x,y,w,h,Color("panel",191))
									
									//Edit field
									do
										local x,y = x+4,y+4
										local w,h = w-8,16
										dat.File.editFilename = dat.File.editFilename or lclib.textEdit(self)
										dat.File.editFilename:Draw(m,x,y,w,h)
									end
									
									local mh = lclib.inRectBoundsW(m.x,m.y,x+4,y+h-16-4,w-8,16)
									do
										surface.SetFont("Trebuchet16")
										local tw = surface.GetTextSize("Open")+8
										local x,y = x+w-tw-4,y+h-16-4
										local w,h = tw,16
										local col = "button_background"
										if mh and lclib.inBoundsW(m.x,x,w) then
											col = "button_highlight"
											
											if m.c[0] == 1 then
												m.dat = {"tabfileopen",k}
												m.c[0] = 2
											elseif m.c[0] == 2 and m.dat[1] == "tabfileopen" and m.dat[2] == k then
												col = "button_press"
											elseif m.c[0] == -1 and m.dat[1] == "tabfileopen" and m.dat[2] == k then
												//Act for open file
												local cur = dat.File.directory..dat.File.editFilename:GetText()
												if file.Exists(cur) then
													dat.Script.content = tostring(file.Read(cur))
													dat.Script.newcontent = true
												end
												self.activeaction = 2
												dat.File.refresh()
											end
										end
										draw.RoundedBox(8,x,y,w,h,Color(col,191))
										draw.DrawText("Open","Trebuchet16",x+tw/2,y,Color("button_text",191),1)
									end
									
									do
										surface.SetFont("Trebuchet16")
										local tw = surface.GetTextSize("Save")+8
										local x,y = x+4,y+h-16-4
										local w,h = tw,16
										local col = "button_background"
										if mh and lclib.inBoundsW(m.x,x,w) then
											col = "button_highlight"
											
											if m.c[0] == 1 then
												m.dat = {"tabfileclose",k}
												m.c[0] = 2
											elseif m.c[0] == 2 and m.dat[1] == "tabfileclose" and m.dat[2] == k then
												col = "button_press"
											elseif m.c[0] == -1 and m.dat[1] == "tabfileclose" and m.dat[2] == k then
												//Act for save file
												local cur = dat.File.directory..dat.File.editFilename:GetText()
												
												if file.Exists(cur) then
													local name = dat.File.editFilename:GetText()
													local cur = dat.File.directory..name
													
													local trash = "luachip/Recycling Bin"
													
													if not file.IsDir(trash) then
														file.CreateDir(trash)
													end
													
													local bin = file.Find(trash.."/*.txt")
													local new = 0
													for k,v in pairs(bin) do
														local num = tonumber(v:sub(1,5))
														if not num then
															file.Delete(trash.."/"..v)
														else
															if num >= new then
																new = num+1
															end
														end
													end
													
													new = tostring(new)
													new = string.rep("0",5-#new)..new
													
													local dest = trash.."/"..new.."_"..name
													file.Rename("data/"..cur,"data/"..dest)
												end
												
												if dat.Script.editScript then
													file.Write(cur,tostring(dat.Script.editScript:GetText()))
												end
												dat.File.refresh()
											end
										end
										draw.RoundedBox(8,x,y,w,h,Color(col,191))
										draw.DrawText("Save","Trebuchet16",x+tw/2,y,Color("button_text",191),1)
									end
									
									do
										surface.SetFont("Trebuchet16")
										local tw = surface.GetTextSize("Delete")+8
										local x,y = x+w/2-tw/2,y+h-16-4
										local w,h = tw,16
										local col = "button_background"
										if mh and lclib.inBoundsW(m.x,x,w) then
											col = "button_highlight"
											
											if m.c[0] == 1 then
												m.dat = {"tabfiledelete",k}
												m.c[0] = 2
											elseif m.c[0] == 2 and m.dat[1] == "tabfiledelete" and m.dat[2] == k then
												col = "button_press"
											elseif m.c[0] == -1 and m.dat[1] == "tabfiledelete" and m.dat[2] == k then
												//Act for delete file/move to bin
												local name = dat.File.editFilename:GetText()
												local cur = dat.File.directory..name
												
												local trash = "luachip/Recycling Bin"
												
												if not file.IsDir(trash) then
													file.CreateDir(trash)
												end
												
												local bin = file.Find(trash.."/*.txt")
												local new = 0
												for k,v in pairs(bin) do
													local num = tonumber(v:sub(1,5))
													if not num then
														file.Delete(trash.."/"..v)
													else
														if num >= new then
															new = num+1
														end
													end
												end
												
												new = tostring(new)
												new = string.rep("0",5-#new)..new
												
												local dest = trash.."/"..new.."_"..name
												file.Rename("data/"..cur,"data/"..dest)
												dat.File.refresh()
											end
										end
										draw.RoundedBox(8,x,y,w,h,Color(col,191))
										draw.DrawText("Delete","Trebuchet16",x+tw/2,y,Color("button_text",191),1)
									end
								end
								
								//File list
								h = h - 44
								
								do
									local w = w-20
									surface.SetFont("LCEdit16")
									local charwidth = surface.GetTextSize("A")
									local chars = math.floor((w-8-20)/charwidth)
									local charheight = math.floor(h/16)
									
									draw.RoundedBox(8,x,y,w,h,Color("edit_background",191))
									//draw.DrawText("data/"..dat.File.directory,"LCEdit16",x+4,y,Color("edit_text"),0)
									//for k,v in pairs(dat.File.list) do
									local scrollpos = dat.File.scrollpos or 1
									local i = 0
									local mh = lclib.inRectBoundsW(m.x,m.y,x,y,w,h)
									local action = nil
									for k = scrollpos,math.min(#dat.File.list,scrollpos-1+charheight) do
										local v = dat.File.list[k]
										i = i+1
										
										local wy = y+(i-1)*16 //Current Y position
										
										//Highlight
										if mh and lclib.inBoundsWE(m.y,wy,16) then
											local col = "edit_highlight"
											
											if m.c[0] == 1 then
												m.dat = {"tabfilelist",k}
												m.c[0] = 2
											elseif m.c[0] == 2 and m.dat[1] == "tabfilelist" and m.dat[2] == k then
												col = "edit_press"
											elseif m.c[0] == -1 and m.dat[1] == "tabfilelist" and m.dat[2] == k then
												action = k
											end
											
											draw.RoundedBox(8,x,wy,w,16,Color(col,127))
										elseif dat.File.editFilename:GetText() == v.name then
											draw.RoundedBox(8,x,wy,w,16,Color("edit_press",191))
										end
										
										//Display
										surface.SetDrawColor(255,255,255,255)
										surface.SetTexture(v.type == "dir" and lclib.tex_folder or lclib.tex_file)
										surface.DrawTexturedRect(x+4,wy,16,16)
										
										local text = v.name
										if #text > chars then
											text = text:sub(1,chars-3).."..."
										end
										draw.DrawText(text,"LCEdit16",x+4+20,wy,Color("edit_text"),0)
									end
									
									if dat.File.editFilename:GetReturn() then
										for k,v in pairs(dat.File.list) do
											if dat.File.editFilename:GetText() == v.name then
												action = k
											end
										end
									end
									
									if action then
										local select = dat.File.list[action]
										
										if select.type == "dir" then
											dat.File.directory = dat.File.directory..select.name.."/"
											dat.File.refresh()
											if dat.File.editFilename:GetReturn() then
												dat.File.editFilename:SetText("")
											end
										elseif select.type == ".txt" then
											dat.File.editFilename:SetText(tostring(select.name))
										end
									end
								end
								
								//Scrollbar
								do
									local x = x+w-20
									local w = 20
									draw.RoundedBox(8,x,y,w,h,Color("panel",191))
									
									//Up
									local mh = lclib.inRectBoundsWE(m.x,m.y,x,y,20,20)
									local col = mh and "button_highlight" or "button_background"
									if mh then
										if m.c[0] == 1 then
											m.dat = {"tabfilescrup"}
											m.c[0] = 2
										elseif m.c[0] == 2 and m.dat[1] == "tabfilescrup" then
											col = "button_press"
										elseif m.c[0] == -1 and m.dat[1] == "tabfilescrup" then
											dat.File.scrollpos = dat.File.scrollpos - 3
										end
									end
									draw.RoundedBox(8,x,y,20,20,Color(col,191))
									
									//Down
									local mh = lclib.inRectBoundsWE(m.x,m.y,x,y+h-20,20,20)
									local col = mh and "button_highlight" or "button_background"
									if mh then
										if m.c[0] == 1 then
											m.dat = {"tabfilescrdn"}
											m.c[0] = 2
										elseif m.c[0] == 2 and m.dat[1] == "tabfilescrdn" then
											col = "button_press"
										elseif m.c[0] == -1 and m.dat[1] == "tabfilescrdn" then
											dat.File.scrollpos = dat.File.scrollpos + 3
										end
									end
									draw.RoundedBox(8,x,y+h-20,20,20,Color(col,191))
									
									//Pixel dimensions
									local sbpixlineh = 16
									local sbpixspace = h-40
									
									//Line dimensions
									local sbnumline = dat.File.scrollpos or 1
									local sbnumlines = #dat.File.list
									local sbnumspace = math.floor(h/16)
									
									//Clamp scrollbar and scroll by wheel
									dat.File.scrollpos = math.Clamp(math.Round(sbnumline-m.c.wheel),1,math.max(sbnumlines-sbnumspace+1,1))
									
									//Recalculate current line
									local sbnumline = dat.File.scrollpos or 1
									
									
									//Find pixel position/height
									local sbpixline = (sbnumline-1)/sbnumlines*sbpixspace
									local sbpixheight = math.min(sbnumspace/sbnumlines*sbpixspace,sbpixspace)
									
									//Scrollbar clicking
									local mh = lclib.inRectBoundsWE(m.x,m.y,x,y+20+sbpixline,20,sbpixheight)
									local col = mh and "button_highlight" or "button_background"
									if mh then
										if m.c[0] == 1 then
											m.dat = {"tabfilescrmi",m.y-(y+20+sbpixline)}
											m.c[0] = 2
										elseif m.c[0] == -1 and m.dat[1] == "tabfilescrmi" then
										end
									end
									if m.c[0] == 2 and m.dat[1] == "tabfilescrmi" then
										local pixpos = m.y-m.dat[2]-y
										dat.File.scrollpos = math.Clamp(math.floor(pixpos/sbpixspace*sbnumlines),1,math.max(sbnumlines-sbnumspace+1,1))
										col = "button_press"
									end
									
									draw.RoundedBox(8,x,y+20+sbpixline,20,sbpixheight,Color(col,191))
									
								end
							end,
						},
						{
							label = "Link",
							act = function()
							end,
							draw = function(x,y,w,h)
								local ent = self:GetNWEntity("curEnt")
								
								if not IsEntity(ent) and ent:IsValid() then
									draw.DrawText("No entity selected.","Trebuchet24",x+4,y,Color("panel_text"),0)
								else
									draw.DrawText("Right-click to link selected entities.","Trebuchet24",x+4,y,Color("panel_text"),0)
									y = y+24
									draw.DrawText(tostring(ent),"Trebuchet24",x+4,y,Color("panel_text"),0)
									y = y+24
									
									local ldat = luachipsweplink
									if ldat and ldat.links and #ldat.links > 0 then
										local mh = lclib.inBoundsW(m.x,x,w)
										
										for k,v in pairs(ldat.links) do
											if not dat.Link.cur then
												dat.Link.cur = 1
											end
											
											local mh = mh and lclib.inBoundsW(m.y,y,32)
											if dat.Link.cur == k or mh then
												
												local col = "edit_highlight"
												if mh then
													col = "button_highlight"
													if m.c[0] == 1 then
														m.dat = {"tablinkcent",k}
														m.c[0] = 2
													elseif m.c[0] == 2 and m.dat[1] == "tablinkcent" and m.dat[2] == k then
														col = "button_press"
													elseif m.c[0] == -1 and m.dat[1] == "tablinkcent" and m.dat[2] == k then
														dat.Link.cur = k
													end
												end
												draw.RoundedBox(8,x,y,w,32,Color(col,191))
											end
											draw.DrawText(tostring(v.description),"Trebuchet16",x+4,y,Color("panel_text"),0)
											draw.DrawText("\t"..tostring(v.id).." : "..tostring(v.ent),"Trebuchet16",x+4,y+16,Color("panel_text"),0)
											y = y+32
										end
										
										
									else
										dat.Link.cur = nil
									end
								end
							end,
						},
					}
					
					if not self.activeaction then
						self.activeaction = self.activeaction or 3
						actions[self.activeaction].act()
					end
					
					draw.RoundedBox(8,x,y,w,32,Color("button_background",191))
					surface.SetFont("Trebuchet32")
					
					local wx = x+8
					local mh = lclib.inBounds(m.y,y,y+32)
					
					local new
					
					for k,v in pairs(actions) do
						local sz = surface.GetTextSize(v.label)+16
						local mh = mh and lclib.inBoundsW(m.x,wx-8,sz)
						
						if mh then
							local col = self.activeaction == k and "button_active" or "button_highlight"
							
							if m.c[0] == 1 then
								m.dat = {"tabactive",k}
								m.c[0] = 2
							elseif m.c[0] == 2 and m.dat[1] == "tabactive" and m.dat[2] == k then
								col = "button_press"
							elseif m.c[0] == -1 and m.dat[1] == "tabactive" and m.dat[2] == k then
								new = k
							end
							
							draw.RoundedBox(8,wx-8,y,sz,32,Color(col,191))
						elseif self.activeaction == k then
							draw.RoundedBox(8,wx-8,y,sz,32,Color(col,191))
						end
						
						draw.DrawText(v.label,"Trebuchet32",wx,y,Color("button_text"),0)
						wx = wx+sz+1
					end
					if new then
						self.activeaction = new
						actions[new].act()
					end
					
					actions[self.activeaction].draw(x,y+32,w,h-32)
				end,
			},
			/*{
				label = "Camera",
				draw = function(x,y,w,h)
					local vp,va = self:GetViewModelPosition(self.Owner:GetShootPos(),self.Owner:EyeAngles())
					
					local sp = Vector(32,5.8,-1.5)
					vp = vp + va:Forward()*sp.x
					vp = vp + va:Right()*sp.y
					vp = vp + va:Up()*sp.z
					
					render.RenderView{
						angles = va,
						origin = vp,
						x = x,
						y = y,
						w = w,
						h = h,
					}
				end,
			},
			{
				label = "Calculator",
				draw = function(x,y,w,h)
					
				end,
			},*/
			{
				label = "Settings",
				draw = function(x,y,w,h)
					local textSize = 40
					local mh = lclib.inBounds(m.y,y,y+textSize)
					do
						surface.SetFont("Trebuchet40")
						local tw = surface.GetTextSize("Joystick Configuration")+8
						local x,y = x+4,y+4
						local w,h = tw,textSize
						local col = "button_background"
						if mh and lclib.inBoundsW(m.x,x,w) then
							col = "button_highlight"
							
							if m.c[0] == 1 then
								m.dat = {"tabsettingsjoystickconfiguration"}
								m.c[0] = 2
							elseif m.c[0] == 2 and m.dat[1] == "tabsettingsjoystickconfiguration" then
								col = "button_press"
							elseif m.c[0] == -1 and m.dat[1] == "tabsettingsjoystickconfiguration" then
								//Act for tabsettingsjoystickconfiguration
								RunConsoleCommand("joyconfig")
							end
						end
						draw.RoundedBox(8,x,y,w,h,Color(col,191))
						draw.DrawText("Joystick Configuration","Trebuchet40",x+tw/2,y,Color("button_text",191),1)
					end
					y = y + textSize
				end,
			},
			{
				label = "Help",
				draw = function(x,y,w,h)
					local dat = self.luachiphelpdata
					if not self.luachiphelpdata then
						self.luachiphelpdata = {}
						dat = self.luachiphelpdata
					end
					do
						local created = dat.editText
						dat.editText = dat.editText or lclib.textEdit(self,{
							multiline = true,
							tabs = true,
							maxchars = false,
							scroll = true,
							wrap = true,
							w = 59,
							write = false,
						})
						
						if not created then
							dat.editText:SetText([[LuaChip

I: Modes
	Unless otherwise specified, this documentation assumes that you are working in the LuaChip tab.
	Sub-tabs and buttons will be listed in [brackets], e.g. [Object], [Script], [File], [Link], [Upload], [Download].
	<select>ing an entity requires shooting a prop, SENT, or other entity with the left-mouse button.
	<altselect>ing an entity requires shooting a prop, SENT, or other entity with the right-mouse button.
	All other actions assume that you are accessing the menu. (By pressing +reload (Default: R) or +menu_context (Default: C))
	
	Exiting the menu may be accomplished by clicking anywhere but the screen. If the script crashes, click the X in the upper-right hand corner of the screen. You must exit the menu before <select>ing or <altselect>ing.

II. Uploading a script
	1. Go to [Object]
	2. <select> an entity
	3. Press [Upload]

III. Using the example car
	1. Go to [File]
	2. Browse to data/luachip/Examples
	3. Open car.txt
	4. Go to [Object]
	5. Switch to the Advanced Duplicator STOOL (Requires Wire)
	6. Upload the LuaChip Example Car.txt file if needed and paste it (Requires PHX Model Pack)
	7. Return to the LuaChip SWEP
	8. <select> the chair
	9. Press [Upload]
	10. Go to [Link]
	11. Exit the menu. While in [Link], select an entity to link it to the currently highlighted entry
	12. Using the mouse wheel to navigate through the entries easily, link Wheel L to the rear left wheel, Wheel R to the rear right wheel, Wheel FL to the front left wheel, Wheel FR to the front right wheel, SteeringHydraulicL to the left siren, and SteeringHydraulicR to the right siren.
	13. Go to [Object] to return the mouse wheel to normal operation
	14. Unfreeze the car and enter the chair. Use WASD to accelerate, brake, and steer.
	(All the following steps require Joystick Module)
	15. Leave the chair, go to the Settings tab, and click Joystick Configuration
	16. Bind your joystick inputs appropriately
	17. Enter the chair and use your joystick to accelerate, brake, and steer.

]])
						end
						
						dat.editText:Draw(m,x,y,w,h)
					end
				end,
			},
		}
		
		local wx = x+8
		local mh = lclib.inBounds(m.y,y,y+24)
		local new
		for k,v in pairs(tabs) do
			local sz = surface.GetTextSize(v.label)+8
			
			local mh = mh and lclib.inBoundsW(m.x,wx,sz)
			
			local col = (mh and self.activetab ~= k) and "panel_highlight" or ((self.activetab ~= k) and "panel_inactive" or "panel")
			if mh then
				if m.c[0] == 1 then
					m.dat = {"tab",k}
					m.c[0] = 2
				elseif m.c[0] == 2 and m.dat[1] == "tab" and m.dat[2] == k then
					col = "panel_press"
				elseif m.c[0] == -1 and m.dat[1] == "tab" and m.dat[2] == k then
					new = k
				end
			end
			
			surface.SetDrawColor(col,191)
			lclib.drawTab(wx,y,sz,24)
			draw.DrawText(v.label,"Trebuchet24",wx+sz/2,y,Color("panel_text"),1)
			
			wx = wx+sz+1
		end
		self.activetab = new or self.activetab
		
		do //Draw
			local y = y+24
			local h = h-24
			
			draw.RoundedBox(8,
				x,y,
				w,h,
				Color("panel",191)
			)
			
			tabs[self.activetab].draw(x,y,w,h)
		end
	end
	
	//Lockdown notice
	
	if luachipgc_CheckKillCode() then
		local text = "LUACHIP LOCKDOWN\nNo more scripts will be executed!\nServer script must be updated to v"..tostring(luachipgc_killcode).."!"
		surface.SetFont("Trebuchet24")
		local tw,th = surface.GetTextSize(text)
		tw = tw + 16
		local d = CurTime()%2 < 1
		surface.SetDrawColor(255,d and 255 or 0,0,255)
		surface.DrawRect(x+w/2-tw/2-16,y+h/2-th/2-16,tw+32,th+32)
		surface.SetDrawColor(255,255,255,255)
		surface.DrawRect(x+w/2-tw/2,y+h/2-th/2,tw,th)
		draw.DrawText(text,"Trebuchet24",x+w/2,y+h/2-th+36,Color(0,0,0,255),1)
	end
	
	//Cursor
	self.Onscreen = m.onscreen
	if m.onscreen then
		if false then
			surface.SetDrawColor(255,255,255,100)
			surface.DrawRect(m.x,m.y,8,8)
			surface.DrawRect(m.x-8,m.y-8,8,8)
			surface.SetDrawColor(0,0,0,100)
			surface.DrawRect(m.x-8,m.y,8,8)
			surface.DrawRect(m.x,m.y-8,8,8)
		elseif true then
			surface.SetDrawColor(255,255,255,100)
			surface.DrawRect(m.x,m.y,8,8)
		end
	else
		for i = 0,4 do
			if m.c[i] == 1 then
				self:MouseActive(false)
				return
			end
		end
	end
	
	if m.c[0] == -1 then
		m.dat = {}
	end
	
	for i = 0,4 do
		if m.c[i] == 1 then
			m.c[i] = 2
		elseif m.c[i] == -1 then
			m.c[i] = 0
		end
	end
	m.c.wheel = 0
	
	self:SaveMouseTable(m)
end
